﻿using Newtonsoft.Json.Linq;
using Org.BouncyCastle.Crypto;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace System
{
    public static class ObjectExtensions
    {
        /// <summary>
        /// 常见数据类型的Null判断。null、DbNull、JsonNull
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsNull(this object obj)
        {
            if (obj == null)
            {
                return true;
            }

            if (obj is DBNull)
            {
                return true;
            }
            if (obj is JValue jv)
            {
                return jv.Type == JTokenType.Null;
            }
            if (Convert.IsDBNull(obj))
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 将对象的属性复制到另一个对象的同名且同类型属性中
        /// </summary>
        /// <param name="obj1"></param>
        /// <param name="obj2"></param>
        public static void CopyTo(this object obj1, object obj2)
        {
            if (obj1 == null)
            {
                throw new ArgumentNullException(nameof(obj1));
            }
            if (obj2 == null)
            {
                throw new ArgumentNullException(nameof(obj2));
            }
            var t1 = obj1.GetType();
            var t2 = obj2.GetType();

            IDictionary<string, object> dic1 = new Dictionary<string, object>();
            if (obj1 is JObject jobj)
            {
                foreach (var p in jobj.Properties())
                {
                    dic1.Add(p.Name, p.Value.ToObject<object>());
                } 
            }
            else if (obj1 is IDictionary<string, object> dic)
            {
                dic1 = dic;
            }
            else
            {
                foreach (var p in t1.GetProperties())
                {
                    dic1.Add(p.Name, p.GetValue(obj1));
                }
            }

            var pis2 = t2.GetProperties();
            foreach (var p2 in pis2)
            {
                if (dic1.ContainsKey(p2.Name))
                {
                    p2.SetValue(obj2, dic1[p2.Name]);
                }
            }
        }
    }
}
